<template>
<div id="createForm">
    <el-form ref="formCreate" :model="formObj" @submit.native.prevent>
        <div v-for="(item, i) in formList" :key="i">
            <el-form-item v-if="item.typeShow&&item.idShow" label-position="top" :prop="item.isRequired?item.charCode:''" :rules="[{ required: item.isRequired, message: item.placeHolder, trigger: ['blur', 'change'] }]">
                <template slot="label" v-if="item.type!=='singleCheckBox'">
                    <span>{{item.label}}</span>
                    <template v-if="item.toolTip">
                        <el-tooltip v-if="item.toolTip.length>12" effect="dark" :content="item.toolTip" placement="top">
                            <div class="my-tool-tip my-len">{{item.toolTip}}</div>
                        </el-tooltip>
                        <span v-else class="my-tool-tip">{{item.toolTip}}</span>
                    </template>
                    <span v-if="item.requiredText" class="my-tool-tip">{{item.requiredText}}</span>
                    <span v-if="item.limitedIntervalText" class="my-tool-tip">{{item.limitedIntervalText}}</span>
                    <el-tooltip v-if="item.longToolTip" effect="dark" :content="item.longToolTip" placement="top">
                        <i class="el-icon-question"></i>
                    </el-tooltip>
                </template>
                <!--弹出弹窗, 单个列选择弹窗-->
                <template v-if="item.type==='singleNumericInputColumnSelect'">
                    <el-input @change="handleChangeInput(item.charCode)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                    <i class="iconfont icon-wenjianjia" @click="handleSelectField('single', i, item.charCode)"></i>
                </template>
                <!--来源表全名输入框，数据库代码 + 表名，字符串数据类型，具体行为待定-->
                <template v-if="item.type==='sourceTableNameInput'">
                    <el-select clearable v-model="formObj[item.charCode]" filterable :placeholder="item.placeHolder" @change="handleChangeInput(item.charCode)">
                        <el-option v-for="(v, i) in tableNames" :key="i" :label="v.fullName" :value="v.fullName"></el-option>
                    </el-select>
                </template>
                <!--数据导入导出-数据源-->
                <template v-if="item.type==='sourceDataInput'">
                    <el-button class="data-origin" @click="handleSelectSource(item.charCode)">选择数据表</el-button>
                </template>
                <!--切分键-->
                <template v-if="item.type==='importSplitKeySelect'">
                    <el-select clearable v-model="formObj[item.charCode]" filterable :placeholder="item.placeHolder" @change="handleChangeInput(item.charCode)">
                        <el-option v-for="(v, i) in selectSource.splitKeyList" :key="i" :label="v" :value="v"></el-option>
                    </el-select>
                </template>
                <!--输入列-->
                <template v-if="item.type==='importColumnSelect'">
                    <select-field :item="item" :list="formObj[item.charCode]" @save="saveSelectCols(item, i)"></select-field>
                </template>
                <!--写入表名称输入框，字符串数据类型，具体行为待定-->
                <template v-if="item.type==='writeTableNameInput'">
                    <el-input @change="changeTableName(item)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                </template>
                <!--sql脚本代码编辑器-->
                <template v-if="item.type==='sqlModeCodeMirror'">
                    <sql-edit :data="formObj[item.charCode]" :tableList="item.valList" @save="handleSqlValue($event, item.charCode)"></sql-edit>
                </template>
                <!--输入数据表变量显示框-->
                <template v-if="item.type==='inputDataTableVariableDisplay'">
                    <table-list :tableList="item.valList"></table-list>
                </template>
                <!--单输入列选择框，单个列选择弹窗-->
                <template v-if="item.type==='singleInputColumnSelect'">
                    <el-input @change="handleChangeInput(item.charCode)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                    <i class="iconfont icon-wenjianjia" @click="handleSelectField('single', i, item.charCode)"></i>
                </template>
                <!--多输入列选择框，多个列选择弹窗，只能选择数值类型的-->
                <template v-if="item.type==='mutipleNumericInputColumnSelect'">
                    <select-field :item="item" :list="formObj[item.charCode]" @save="handleSelectField('multiple', i, item.charCode, true)"></select-field>
                </template>
                <!--多输入列选择框，多个列选择弹窗-->
                <template v-if="item.type==='mutipleInputColumnSelect'">
                    <select-field :item="item" :list="formObj[item.charCode]" @save="handleSelectField('multiple', i, item.charCode)"></select-field>
                </template>
                <!--连接条件列选择框，左右连接条件列选择弹窗，暂时不做-->
                <template v-if="item.type==='joinConditionColumnSelect'">
                    <el-input @change="handleChangeInput(item.charCode)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                </template>
                <!--左边输入列选择框，多个列选择弹窗-->
                <template v-if="item.type==='leftInputColumnsSelect'">
                    <select-field :item="item" :list="formObj[item.charCode]" @save="handleSelectField('multiple', i, item.charCode)"></select-field>
                </template>
                <!--右边输入列选择框，多个列选择弹窗-->
                <template v-if="item.type==='rightInputColumnsSelect'">
                    <select-field :item="item" :list="formObj[item.charCode]" @save="handleSelectField('multiple', i, item.charCode)"></select-field>
                </template>
                <!--表字段信息，暂不提供-->
                <template v-if="item.type==='tableColumnInfo'">
                    <el-input @change="handleChangeInput(item.charCode)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                </template>
                <!--调参类型单值输入框-->
                <template v-if="item.type==='tuningParameterValueInput'">
                    <el-input @change="handleChangeInput(item.charCode, true, item.charType)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode].value"></el-input>
                </template>
                <!--调参类型复合输入框-->
                <template v-if="item.type==='tuningParameterComplexInput'">
                    <div class="row-input" v-if="item.showRange">
                        <el-input oninput="value=value.replace(/[^\d.]/g,'')" @change="handleChangeInput(item.charCode, true, item.charType)" :disabled="item.isDisabled" clearable placeholder="请输入" v-model="formObj[item.charCode].tuneRange.start"></el-input>
                        <span class="contact-span">-</span>
                        <el-input oninput="value=value.replace(/[^\d.]/g,'')" @change="handleChangeInput(item.charCode, true, item.charType)" :disabled="item.isDisabled" clearable placeholder="请输入" v-model="formObj[item.charCode].tuneRange.end"></el-input>
                    </div>
                    <div class="row-input" v-else>
                        <el-input @change="handleChangeInput(item.charCode, true, item.charType)" :disabled="item.isDisabled" clearable placeholder="请输入" v-model="formObj[item.charCode].tuneUdps"></el-input>
                    </div>
                </template>
                <!--单选下拉框，适用于枚举限定的特征，通常为字符串数据类型-->
                <template v-if="item.type==='select'">
                    <el-select @change="changeVal($event, item)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]">
                        <el-option v-for="item in item.options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
                    </el-select>
                </template>
                <!--单个复选框，适用于布尔值数据类型-->
                <template v-if="item.type==='singleCheckBox'">
                    <el-checkbox @change="changeVal($event, item, true)" :disabled="item.isDisabled" v-model="formObj[item.charCode]">{{item.label}}</el-checkbox>
                </template>
                <!--整数值输入框-->
                <template v-if="item.type==='number'">
                    <el-input oninput="value=value.replace(/[^\d]/g,'')" @change="handleChangeInput(item.charCode)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                </template>
                <!--浮点数输入框-->
                <template v-if="item.type==='float'">
                    <el-input oninput="value=value.replace(/[^\d.]/g,'')" @change="handleChangeInput(item.charCode)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                </template>
                <!--字符串输入框-->
                <template v-if="item.type==='string'">
                    <el-input @change="handleChangeInput(item.charCode)" :disabled="item.isDisabled" clearable :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                </template>
                <!--多行文本输入框-->
                <template v-if="item.type==='textarea'">
                    <el-input @change="handleChangeInput(item.charCode)" :disabled="item.isDisabled" type="textarea" :rows="4" :placeholder="item.placeHolder" v-model="formObj[item.charCode]"></el-input>
                </template>
            </el-form-item>
        </div>
        <!--连续性，缺失值字段设置-->
        <el-form-item v-show="numStrategy" label-position="top">
            <template slot="label">
                <span>连续型自定义值</span>
                <span class="my-tool-tip">（必填）</span>
            </template>
            <el-button class="select-btn" @click="handleLossSet('numUserDefined')">缺失值设置</el-button>
        </el-form-item>
        <!--离散型，缺失值字段设置-->
        <el-form-item v-show="strStrategy" label-position="top">
            <template slot="label">
                <span>离散型自定义值</span>
                <span class="my-tool-tip">（必填）</span>
            </template>
            <el-button class="select-btn" @click="handleLossSet('strUserDefined')">缺失值设置</el-button>
        </el-form-item>
    </el-form>
    <loss-set v-if="lossSet.show" :data="lossSet" @save="saveLossSet"></loss-set>
    <select-source v-if="selectSource.show" :data="selectSource" @save="saveSourceData"></select-source>
</div>
</template>

<script>
import TableList from '@/components/TableList'
import SqlEdit from '@/components/SqlEdit'
import SelectField from '@/components/SelectField'
import SelectSource from './SelectSource'
import LossSet from './LossSet'
import { mapGetters } from 'vuex'

export default {
    name: 'FormCreate',
    components: {
        SqlEdit,
        TableList,
        LossSet,
        SelectField,
        SelectSource
    },
    props: {
        tableNames: {
            type: Array
        },
        // 表单需要传给后台的字段
        formObj: {
            type: Object
        },
        // 表单控件
        formList: {
            type: Array,
            required: true,
            default: () => { return [] }
        }
    },
    computed: {
        ...mapGetters({
            projectId: 'common/getProjectId',
            experimentId: 'common/getExperimentId',
            nodeData: 'common/getNodeData'
        })
    },
    data () {
        return {
            lossSet: {
                show: false,
                charCode: '',
                list: []
            },
            numStrategy: false,
            strStrategy: false,
            selectSource: {
                show: false,
                charCode: '',
                title: '选择数据表',
                defaultValue: '',
                splitKeyList: [],
                inputColumns: []
            }
        }
    },
    created () {
        this.initSetShowOrHide()
    },
    methods: {
        handleSelectField (type, index, charCode, flag, schema) {
            this.$emit('selectField', type, index, this.formObj[charCode], flag, schema)
        },
        handleChangeInput (charCode, flag, charType) {
            this.$emit('updateControl', charCode, this.formObj[charCode], flag, charType)
        },
        handleLossSet (charCode) {
            const params = {
                projectId: this.projectId,
                experimentId: this.experimentId,
                nodeId: this.nodeData.nodeId
            }
            this.$post('/experiment/extend/queryInputFeatureColumns', params).then(res => {
                this.lossSet = {
                    show: true,
                    charCode,
                    allList: res.inputDataSources[0].schema || [],
                    list: this.formObj.featureColumnNames
                }
            })
        },
        getSchema (item, i) {
            const { databaseSchema, sourceId, srcTableName } = this.formObj['sourceData']
            const url = '/dataSource/file-upload/previewDataTable'
            const params = {
                projectId: this.projectId,
                sourceId,
                tableName: srcTableName,
                databaseSchema,
                inputColumns: []
            }
            this.$post(url, params).then(res => {
                if (res) {
                    this.handleSelectField('multiple', i, item.charCode, false, res.schema)
                }
            })
        },
        saveSelectCols (item, i) {
            const arr = this.selectSource.inputColumns
            if (arr.length) {
                this.handleSelectField('multiple', i, item.charCode, false, arr)
            } else {
                this.getSchema(item, i)
            }
        },
        saveLossSet (val) {
            let charCode = this.lossSet.charCode
            this.formObj[charCode] = val
            this.$emit('updateControl', charCode, JSON.stringify(val))
        },
        saveSourceData (val) {
            let charCode = this.selectSource.charCode
            this.formObj[charCode] = val
            this.$emit('updateControl', charCode, JSON.stringify(val))
        },
        // 选择数据源
        handleSelectSource (charCode) {
            this.selectSource = {
                show: true,
                charCode,
                title: '选择数据表',
                defaultValue: this.formObj[charCode],
                splitKeyList: [],
                inputColumns: []
            }
        },
        // 写数据表判断是否有重复表名
        changeTableName (item) {
            let value = this.formObj[item.charCode]
            if (!value) {
                return
            }
            const params = {
                projectId: this.projectId,
                tableName: value
            }
            this.$post('/dataSource/existsDataTable', params).then(res => {
                if (res) {
                    this.$confirm('该表名已存在，确定使用此表名后，现有文件内容将会替换原文件，确定继续使用此表名吗？', '提示', {
                        confirmButtonText: '确 定',
                        cancelButtonText: '取 消',
                        type: 'warning'
                    }).then(() => {
                        this.$emit('updateControl', item.charCode, value)
                    }).catch(() => {})
                } else {
                    this.$emit('updateControl', item.charCode, value)
                }
            })
        },
        // 初始化配置右侧表单控件显示隐藏
        initSetShowOrHide () {
            let arr = this.formList
            for (let i = 0; i < arr.length; i++) {
                const { relations, paramValue, charCode } = arr[i]
                this.getStrategy(paramValue, charCode)
                if (relations) {
                    this.setShowOrHide(relations, paramValue)
                }
            }
        },
        // 缺失值判断
        getStrategy (paramValue, charCode) {
            if (['numStrategy', 'strStrategy'].includes(charCode)) {
                this[charCode] = paramValue === 'userDefined'
            }
        },
        // 配置右侧表单控件显示隐藏
        setShowOrHide (subArr, val) {
            let arr = this.formList
            for (let i = 0; i < arr.length; i++) {
                for (let n = 0; n < subArr.length; n++) {
                    let idFlag = subArr[n].targetSelect === 'control-id' && `${arr[i].controlId}` === subArr[n].targetObject && val === subArr[n].controlValue
                    let typeFlag = subArr[n].targetSelect === 'control-type' && arr[i].type === subArr[n].targetObject && val === subArr[n].controlValue
                    if (idFlag || typeFlag) {
                        if (subArr[n].relation === 'hide') {
                            arr[i].idShow = false
                        }
                        if (subArr[n].relation === 'show') {
                            arr[i].idShow = true
                        }
                        if (subArr[n].relation === 'turn2TuneRange') {
                            arr[i].showRange = true
                        }
                        if (subArr[n].relation === 'turn2TuneUdps') {
                            arr[i].showRange = false
                        }
                    }
                }
            }
        },
        handleSqlValue (val, charCode) {
            this.$emit('updateControl', charCode, val)
        },
        changeVal (val, item, flag) {
            this.getStrategy(val, item.charCode)
            if (val !== '' && !flag) {
                this.setShowOrHide(item.relations, val)
            }
            this.$emit('updateControl', item.charCode, val)
        }
    }
}
</script>

<style lang="less">
#createForm {
    .select-btn {
        width: 100%;
    }
    .el-form-item {
        margin-bottom: 10px !important;

        .el-form-item__label {
            font-size: 12px;
        }

        .el-checkbox__label {
            font-size: 12px;
        }
    }
    .data-origin {
        width: 100%;
    }
    .my-tool-tip {
        text-align: left;
        font-size: 12px;
        padding: 0 5px;
        color: #919297;
    }

    .contact-span {
        padding: 0 5px;
        color: #999999;
    }

    .row-input {
        display: flex;
        flex-direction: row;
        width: 100%;
    }

    .el-form-item__label {
        float: initial;
    }

    .icon-wenjianjia {
        font-size: 20px;
        margin-left: 5px;
        cursor: pointer;
    }

    .sql-editor {
        width: 100%;
        border-radius: 4px;
        overflow: hidden;
    }
    .my-len {
        width: 150px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .el-form-item__label {
        display: flex;
        align-items: center;
    }
}
</style>
